Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] : 에러 처리를 추가하며, 메세지를 정제하여 전달한다 #24

Merged
merged 6 commits into from
Oct 20, 2024

Conversation

bbbang105
Copy link
Contributor

@bbbang105 bbbang105 commented Oct 20, 2024

✅ PR 유형

어떤 변경 사항이 있었나요?

  • 새로운 기능 추가
  • 버그 수정
  • 코드에 영향을 주지 않는 변경사항(오타 수정, 탭 사이즈 변경, 변수명 변경)
  • 코드 리팩토링
  • 주석 추가 및 수정
  • 문서 수정
  • 빌드 부분 혹은 패키지 매니저 수정
  • 파일 혹은 폴더명 수정
  • 파일 혹은 폴더 삭제

📝 작업 내용

이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

@PathParam -> @RequestParam 으로 변경

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/chatbot")
@Validated
public class ChatbotController {
    private final ChatbotService chatbotService;
    private final ClovaService clovaService;

    // 가이드 챗봇 답변 조회 API
    @GetMapping("/guide")
    public ResponseEntity<ApiResponse<GetGuideChatbotAnswerResponse>> getGuideChatbotAnswer(
            @RequestParam("stadiumName") @NotBlank String stadiumName,
            @RequestParam("categoryName") @NotBlank String categoryName,
            @RequestParam("orderNumber") @Min(1) int orderNumber){

        GetGuideChatbotAnswerResponse response = chatbotService.getGuideChatbotAnswer(stadiumName, categoryName, orderNumber);

        return ApiResponse.onSuccess(ChatbotSuccessStatus._GET_GUIDE_CHATBOT_ANSWER, response);
    }
  • 클래스단에 @Validated 어노테이션을 붙이고, 파라미터에 @NotBlank, @Min(1) 어노테이션을 붙이며 파라미터에 대한 유효성 검증을 추가하였습니다.
  • @Validated 어노테이션을 붙이지 않는다면 파라미터에 대한 유효성 검증이 제대로 되지 않습니다. (RequestBody에는 @Valid만 붙이면 가능합니다)

ConstraintViolationException 처리 (쿼리 파라미터에 올바른 값이 들어오지 않은 경우)

image

MissingServletRequestParameterException 처리 (필수 쿼리 파라미터가 입력되지 않은 경우)

image

MethodArgumentNotValidException 처리 추가

    // MethodArgumentNotValidException 처리 (RequestBody로 들어온 필드들의 유효성 검증에 실패한 경우)
    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers,
                                                                  HttpStatusCode status,
                                                                  WebRequest request) {
        String combinedErrors = extractFieldErrors(ex.getBindingResult().getFieldErrors());
        logError("Validation error", combinedErrors);
        return ApiResponse.onFailure(ErrorStatus._BAD_REQUEST, combinedErrors);
    }
  • @Override를 통해서 에러 처리를 추가했습니다.

MethodArgumentNotValidException 처리 (RequestBody로 들어온 필드들의 유효성 검증에 실패한 경우)

image
  • 레코드에 지정한 메세지대로 반환합니다.

그 외 에러 처리 추가

  • IllegalArgumentException 처리 (잘못된 인자가 전달된 경우)
  • NoHandlerFoundException 처리 (요청 경로에 매핑된 핸들러가 없는 경우)
  • HttpRequestMethodNotSupportedException 처리 (지원하지 않는 HTTP 메소드 요청이 들어온 경우)
  • HttpMediaTypeNotSupportedException 처리 (지원하지 않는 미디어 타입 요청이 들어온 경우)

HttpRequestMethodNotSupportedException 처리 (지원하지 않는 HTTP 메소드 요청이 들어온 경우)

image

내부 서버 에러 처리 (500) 응답 변경

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiResponse<ErrorReasonDto>> handleException(Exception e) {
        // 서버 내부 에러 발생 시 로그에 예외 내용 기록
        logError(e.getMessage(), e);
        return ApiResponse.onFailure(ErrorStatus._INTERNAL_SERVER_ERROR);
    }
_INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR,"500", "서버 내부 오류가 발생했습니다. 자세한 사항은 백엔드 팀에 문의하세요."),
  • 내부 서버 에러 발생 시 정해진 메세지를 반환합니다.
  • 자세한 에러 내용은 로그를 통해서 확인합니다.

✏️ 관련 이슈

본인이 작업한 내용이 어떤 Issue Number와 관련이 있는지만 작성해주세요


🎸 기타 사항 or 추가 코멘트

하면서 에러 처리에 대한 강제 학습이 된 것 같습니다...
저도 나중에 다시 볼 겸 도움 됐던 블로그 글들 정리해둡니다!

  1. 커스텀 에러 처리 흐름
  2. ResponseEntityExceptionHandler를 사용해야 하는 이유
  3. (최신 버전 이걸로 해결함!) @Valid MethodArgumentNotValidException 처리
  4. (ConstraintViolationException 처리) @Valid, @Validated 차이점 분석해서 유효성 검사 적용하기
  5. (MissingServletRequestParameterException 처리) @RequestParam null 일 경우, exception handler 처리

@bbbang105 bbbang105 added 🚨 fix 버그 수정 / 에러 해결 🚀 feat 새로운 기능 추가 / 일부 코드 추가 / 일부 코드 수정 (리팩토링과 구분) / 디자인 요소 수정 🤯 SANGHO 상호 Issue or PR labels Oct 20, 2024
@bbbang105 bbbang105 self-assigned this Oct 20, 2024
Copy link
Contributor

@juuuunny juuuunny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정말 수고 많았습니다!!
이 에러 처리들은 나중에도 두고두고 쓸 수 있을 거 같아요!!

logError("MissingServletRequestParameterException", errorMessage);
return ApiResponse.onFailure(ErrorStatus._BAD_REQUEST, errorMessage);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 필수 파라미터 여러개 값이 없으면 여러개 다에 대해서 에러메시지 난오는 거죠???

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거는 파라미터 1개마다 각각 에러가 발생해서 1개만 처리가 되더라구요 ㅠ
가능하면 다음에 여러개를 동시에 처리할 수 있는 방법을 찾아봐도 좋을 것 같네요!

@juuuunny
Copy link
Contributor

아 추가로 RequestBody에서도 Valid말고 Validated 써도 돼요!!
@validated로 통일해도 상관없을듯

주요 차이점
@Valid: 단순한 유효성 검사. 그룹 기능이 없고 표준 Java Bean Validation API의 일부.
@validated: Spring에서 제공하며, 유효성 검사 그룹을 사용하여 여러 상황에서 다른 검증을 수행할 수 있음.

언제 사용해야 하나?
간단한 유효성 검사만 필요하다면 @Valid를 사용하면 충분합니다.
그룹 기반 유효성 검사가 필요한 경우 @validated를 사용해야 합니다. 예를 들어, 객체의 상태에 따라 다른 필드를 검증해야 할 때 적합합니다.

@bbbang105
Copy link
Contributor Author

아 추가로 RequestBody에서도 Valid말고 Validated 써도 돼요!! @validated로 통일해도 상관없을듯

주요 차이점 @Valid: 단순한 유효성 검사. 그룹 기능이 없고 표준 Java Bean Validation API의 일부. @validated: Spring에서 제공하며, 유효성 검사 그룹을 사용하여 여러 상황에서 다른 검증을 수행할 수 있음.

언제 사용해야 하나? 간단한 유효성 검사만 필요하다면 @Valid를 사용하면 충분합니다. 그룹 기반 유효성 검사가 필요한 경우 @validated를 사용해야 합니다. 예를 들어, 객체의 상태에 따라 다른 필드를 검증해야 할 때 적합합니다.

오호 굿굿 그러면 클래스단에 @Validated만 붙여도 다 처리 되려나요..? 한 번 해봐야겠네

@bbbang105
Copy link
Contributor Author

아 추가로 RequestBody에서도 Valid말고 Validated 써도 돼요!! @validated로 통일해도 상관없을듯
주요 차이점 @Valid: 단순한 유효성 검사. 그룹 기능이 없고 표준 Java Bean Validation API의 일부. @validated: Spring에서 제공하며, 유효성 검사 그룹을 사용하여 여러 상황에서 다른 검증을 수행할 수 있음.
언제 사용해야 하나? 간단한 유효성 검사만 필요하다면 @Valid를 사용하면 충분합니다. 그룹 기반 유효성 검사가 필요한 경우 @validated를 사용해야 합니다. 예를 들어, 객체의 상태에 따라 다른 필드를 검증해야 할 때 적합합니다.

오호 굿굿 그러면 클래스단에 @Validated만 붙여도 다 처리 되려나요..? 한 번 해봐야겠네

이건 안되네요 ㅎㅎ

@Valid vs @Validated 정리

제 생각에는 기존처럼 RequestBody에는 @Valid로 붙이고, 이번처럼 쿼리 파라미터에 대한 검증이 필요할 때는 클래스단에 @Validated를 붙이는 게 좋을 것 같은데 어떠세요???

@bbbang105 bbbang105 merged commit 93cefa0 into develop Oct 20, 2024
1 check passed
@bbbang105 bbbang105 deleted the feature/#23/handle-valid-error branch October 20, 2024 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🚀 feat 새로운 기능 추가 / 일부 코드 추가 / 일부 코드 수정 (리팩토링과 구분) / 디자인 요소 수정 🚨 fix 버그 수정 / 에러 해결 🤯 SANGHO 상호 Issue or PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feat] : 유효성 검증 에러를 처리할 수 있다
2 participants